/**
 * 
 */
package nl.boektrust.btsoep.server;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;

import nl.boektrust.btsoep.shared.model.BTEntity;
import nl.boektrust.btsoep.shared.model.Book;
import nl.boektrust.btsoep.shared.model.BookManifestation;
import nl.boektrust.btsoep.shared.model.Person;
import nl.boektrust.btsoep.shared.model.PhysicalBookManifestation;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.googlecode.objectify.ObjectifyService;

/**
 * @author rao3
 *
 */
public class RestBook extends RemoteServiceServlet {
	private boolean isObjectifyServiceRegistered = false;
	PersistentServiceImpl persistentServiceImpl = new PersistentServiceImpl();

	/**
	 * 
	 */
	public RestBook() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * @param delegate
	 */
	public RestBook(Object delegate) {
		super(delegate);
		// TODO Auto-generated constructor stub
	}
	
	
	
	
	public void doGet(HttpServletRequest request, HttpServletResponse response)
	throws ServletException, IOException {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		Document doc = null;
		try {
			doc = factory.newDocumentBuilder().newDocument();
		} catch (Exception e) {
			System.err.println("Exception");
			e.printStackTrace();

			System.err.println(e.getMessage());
			System.err.println(e.getStackTrace());
			return;
		}
		 
		PrintWriter out = response.getWriter();
		response.setContentType("text/xml");
		if (request.getPathInfo() == null || request.getPathInfo().length()<13) {
			out.println("Error: no ISBN specified; usage: http://.../book/978906262331");
			return;
		}
		String isbnString = request.getPathInfo().substring(1);
		System.err.println("RestBook called with ISBN "+isbnString);

		isbnString = isbnString.substring(0, 12);
		System.err.println("Matching on substring "+isbnString);

		List<PhysicalBookManifestation> books = persistentServiceImpl.getBooksByISBN(isbnString);
		System.err.println("Got " + books.size() + " books");
		if (books.size() > 0) {
			PhysicalBookManifestation theBook = books.get(0);
			System.err.println("First book: " +theBook.toPrintString());

			// 	encode the message
			DocumentFragment onixMessage = OnixUtility.getOnixMessage();
			if (onixMessage == null) {
				System.err.println("fragment is null");
				return;
			}
			doc.appendChild(doc.importNode(onixMessage, true));
			if (onixMessage.getOwnerDocument() == null) {
				System.err.println("owner document is null");
				return;
			}
			// add header
			DocumentFragment header = OnixUtility.getOnixMessageHeader();
			doc.getDocumentElement().appendChild(doc.importNode(header, true));
			
			// add product node for first product
			DocumentFragment product = OnixUtility.encodeToOnix(theBook);
			doc.getDocumentElement().appendChild(doc.importNode(product, true));
			/*
			System.out.println("Built an XML docFragment with "+onixMessage.getChildNodes().getLength()+" nodes");
			System.out.println("Nodes: ");
			for (int i = 0; i<onixMessage.getChildNodes().getLength(); i++) {
				System.out.println("node "+i+": "+onixMessage.getChildNodes().item(i).getNodeName());
				System.out.println("      has : "+onixMessage.getChildNodes().item(i).getChildNodes().getLength()+" children");
			}
			*/

			// transform and output the book
			Transformer transformer;
			try {
				// see: http://comments.gmane.org/gmane.org.google.gwt/45531
				System.setProperty("javax.xml.transform.TransformerFactory", "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl");
				transformer = TransformerFactory.newInstance().newTransformer();
				//transformer.setOutputProperty(OutputKeys.INDENT, "yes");
				//javax.xml.transform.Source src = new DOMSource(docFragment.getOwnerDocument());
				//if (src == null) out.println("src is null");
				java.io.StringWriter writer = new StringWriter();
				javax.xml.transform.stream.StreamResult result = new javax.xml.transform.stream.StreamResult(writer);
				DOMSource source = new DOMSource(doc);
				//out.println("Got an XML; root node has  "+doc.getDocumentElement().getChildNodes().getLength()+" nodes");
				//out.println("First node under rootnode: "+doc.getDocumentElement().getChildNodes().item(0).getNodeName());
				transformer.transform(source, result);
				String xmlString = result.getWriter().toString();
				if (xmlString == null) out.println("xmlString is null");
				System.err.println("xmlString: " + xmlString);
				out.println("" + xmlString);
			} catch (Exception e) {
				System.err.println("Exception thrown: " + e.getMessage());
				out.print("Exception thrown: " + e.getMessage());
				e.printStackTrace();
			}

			
		} else {
			response.sendError(404);
		}
	}
	
	
	public static final void prettyPrint(Node xml, PrintWriter out)
	throws TransformerConfigurationException, TransformerFactoryConfigurationError, TransformerException {
		Transformer tf = TransformerFactory.newInstance().newTransformer();
		tf.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
		tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
		tf.setOutputProperty(OutputKeys.INDENT, "yes");
		tf.transform(new DOMSource(xml), new StreamResult(out));
	}

}
